home *** CD-ROM | disk | FTP | other *** search
- dosseg
- locals
-
- .model large
-
- .code
-
- ;-----------------------------------------------------------------------------
- ; void swinterrupt(byte intno, db_regs *inregs, db_regs *outregs);
- ;-----------------------------------------------------------------------------
- public _swinterrupt
-
- db_regs struc
- rax dw ?
- rbx dw ?
- rcx dw ?
- rdx dw ?
- rsi dw ?
- rdi dw ?
- rcflag dw ?
- rflags dw ?
- db_regs ends
-
- _swinterrupt proc
- arg intno:byte,inregs:dword,outregs:dword
- push bp
- mov bp,sp ; link stack
- push si ; save regs
- push di
- push ds
- mov al,intno ; set interrupt number
- mov cs:no,al
- lds bx,inregs ; get source regs
- mov ax,[bx].rax ; load regs
- mov cx,[bx].rcx
- mov dx,[bx].rdx
- mov si,[bx].rsi
- mov di,[bx].rdi
- mov bx,[bx].rbx
- intr db 0CDh ; int
- no db ? ; int number
- push bx ; save return reg BX
- lds bx,outregs ; get dest regs
- mov [bx].rax,ax ; set return regs
- pop ax ; restore return reg BX
- mov [bx].rbx,ax
- mov [bx].rcx,cx
- mov [bx].rdx,dx
- mov [bx].rsi,si
- mov [bx].rdi,di
- pushf ; set flags
- pop ax
- mov [bx].rflags,ax
- and ax,0001h
- mov [bx].rcflag,ax
- pop ds ; restore regs
- pop di
- pop si
- pop bp
- ret
- _swinterrupt endp
-
- ;-----------------------------------------------------------------------------
- ; void db_delay(word msecs);
- ;-----------------------------------------------------------------------------
- public _db_delay
-
- msecspertick dw 55 ; number of msecs in one timer tick
- delaycount dw 0 ; 1ms delay count
-
- _db_delay proc
- arg msecs:word
- push bp ; link stack
- mov bp,sp
- push ds
- cmp cs:delaycount,0 ; see if been initialized
- jne @@dodelay ; y
- xor dx,dx ; init hi word of count
- mov ds,dx ; point at system tick count
- mov bx,46Ch ; 0000:046Ch
- @@synch1: test byte ptr [bx],1 ; wait for 1
- jz @@synch1
- @@synch2: test byte ptr [bx],1 ; wait for 0
- jnz @@synch2
- @@start: xor cx,cx
- even
- @@timing: test byte ptr [bx],1 ; loop while still 0
- jnz @@stop ; done
- loop @@timing ; keep timing
- inc dx ; keep overflow
- jmp short @@start
-
- @@stop: xor ax,ax ; calc number done
- sub ax,cx
- div cs:msecspertick ; calc delay wait
- mov cs:delaycount,ax ; save
- @@dodelay: mov cx,msecs ; get number of msecs to wait
- jcxz @@exit ; exit if no wait
- push cs ; setup DS:BX to point at a
- pop ds ; guaranteed non-zero value
- mov bx,offset msecspertick
- @@delay: push cx
- mov cx,cs:delaycount ; get delay count
- even
- @@delay1ms: test byte ptr [bx],0FFh ; test to simulate same timing
- je @@bogus ; this should never branch
- loop @@delay1ms
- @@bogus: pop cx
- loop @@delay
- @@exit: pop ds ; done
- pop bp
- ret
- _db_delay endp
-
- ;-----------------------------------------------------------------------------
- ; void db_sound(word freq);
- ;-----------------------------------------------------------------------------
- public _db_sound
-
- PPI_B equ 61h ; PPI port B
- speaker_on equ 03h ; speaker control bits
- TIMER_2 equ 42h ; speaker timer count reg
- TIMER_MODE equ 43h ; timer mode reg
- sound_mode equ 0B6h ; timer 2 select, word count, binary
- clock_hi equ 0012h ; input clock speed of 1,193,180 Hz
- clock_lo equ 34DCh
-
- _db_sound proc
- arg freq:word
- push bp ; link stack
- mov bp,sp
- xor ax,ax ; set min freq limit
- mov cx,freq ; get frequency required in Hz
- mov dx,clock_hi ; set hi word 1 Hz divisor
- cmp dx,cx ; check if below min freq
- jae @@settimer ; y - set to minimum Hz
- mov ax,clock_lo ; n - set lo word 1 Hz divisor
- div cx ; calc required divisor
- @@settimer: mov bx,ax ; save divisor
- mov al,sound_mode ; setup timer channel 2
- out TIMER_MODE,al
- mov al,bl ; timer 2 LSB
- out TIMER_2,al
- mov al,bh ; timer 2 MSB
- out TIMER_2,al
- in al,PPI_B ; enable speaker
- or al,speaker_on
- out PPI_B,al
- pop bp
- ret
- _db_sound endp
-
- ;-----------------------------------------------------------------------------
- ; void db_nosound(void);
- ;-----------------------------------------------------------------------------
- public _db_nosound
-
- _db_nosound proc
- in al,PPI_B ; get PPI
- and al,not speaker_on ; mask off speaker
- out PPI_B,al ; set PPI
- ret
- _db_nosound endp
-
- ;-----------------------------------------------------------------------------
-
- end
-